package app.util.image.action
{
	import flash.display.*;
	import flash.filters.*;
	import flash.geom.*;
	
	public class EdgeDetector
	{
		public static function getSobelEdge(data:BitmapData, invertColor:Boolean = false):BitmapData
		{
			var hFilter:ConvolutionFilter = new ConvolutionFilter
				(3, 3,
				[
					-1, -2, -1,
					 0,  0,  0,
					 1,  2,  1,
				]
				);
			var vFilter:ConvolutionFilter = new ConvolutionFilter
				(3, 3,
				[
					-1, 0, 1,
					-2, 0, 2,
					-1, 0, 1,
				]
				);
			return getEdgeFromConvolution(data, hFilter, vFilter, invertColor);	
		}
		
		public static function getPrewittEdge(data:BitmapData, invertColor:Boolean = false):BitmapData
		{
			var hFilter:ConvolutionFilter = new ConvolutionFilter
				(3, 3,
				[
					-1, -1, -1,
					 0,  0,  0,
					 1,  1,  1,
				]
				);
			var vFilter:ConvolutionFilter = new ConvolutionFilter
				(3, 3,
				[
					-1, 0, 1,
					-1, 0, 1,
					-1, 0, 1,
				]
				);
			return getEdgeFromConvolution(data, hFilter, vFilter, invertColor);				
		}
		
		public static function getLaplaceEdge(data:BitmapData):BitmapData
		{
			var ret:BitmapData = data.clone();
			var filter:ConvolutionFilter = new ConvolutionFilter(3, 3, 
				[
				 0, -1, 0,
				-1,  4, -1, 
 				 0, -1, 0,
				]);
			ret.applyFilter(ret, ret.rect, new Point(0, 0), filter);
			return ret;
		}

		private static function getEdgeFromConvolution(data:BitmapData, 
			hFilter:ConvolutionFilter, vFilter:ConvolutionFilter, invertColor:Boolean):BitmapData
		{
			var ret:BitmapData = data.clone();
			var grayMatrix:Array = [ 0.3, 0.59, 0.11, 0, 0, 
									 0.3, 0.59, 0.11, 0, 0,
									 0.3, 0.59, 0.11, 0, 0,
									 0,   0,    0,    1, 0]; 
			var invertMatrix:Array = [-1, 0, 0, 0, 255, 
							 		  0, -1, 0, 0, 255,
							 		  0, 0, -1, 0, 255,
							 		  0, 0, 0, 1, 0];
			
			ret.applyFilter(ret, ret.rect, new Point(0, 0), new ColorMatrixFilter(grayMatrix));
			var t1:BitmapData = ret.clone();
			var t2:BitmapData = ret.clone();
			t1.applyFilter(t1, t1.rect, new Point(0, 0), hFilter);
			t2.applyFilter(t2, t2.rect, new Point(0, 0), vFilter);
			
			ret.applyFilter(ret, ret.rect, new Point(0, 0), new ColorMatrixFilter(invertMatrix));
			var t3:BitmapData = ret.clone();
			var t4:BitmapData = ret.clone();
			t3.applyFilter(t3, t3.rect, new Point(0, 0), hFilter);
			t4.applyFilter(t4, t4.rect, new Point(0, 0), vFilter);
			
			ret.draw(t1);
			ret.draw(t3, null, null, BlendMode.ADD);
			ret.draw(t2, null, null, BlendMode.ADD);
			ret.draw(t4, null, null, BlendMode.ADD);
			if(invertColor)
			{
				ret.applyFilter(ret, ret.rect, new Point(0, 0), new ColorMatrixFilter(invertMatrix));
			}
			
			return ret;
		}
	}
}